package de.upb.messerschmidt.set;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.gson.Gson;

import de.upb.messerschmidt.set.entity.Event;
import de.upb.messerschmidt.set.entity.EventStatus;
import de.upb.messerschmidt.set.entity.Location;
import de.upb.messerschmidt.set.entity.Person;
import de.upb.messerschmidt.set.jdo.PMF;

/**
 * This Servlet returns all {@link Event}s for a specific {@link Location}, {@link Person} or every
 * event registerd.
 * 
 * @author Tim Messerschmidt
 * 
 */
public class GetEventServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@SuppressWarnings("unchecked")
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		String title = req.getParameter("title");
		String location = req.getParameter("location");
		String name = req.getParameter("name");
		String prename = req.getParameter("prename");

		List<Event> toJson = new ArrayList<Event>();

		// Is this a query for a location?
		if (location != null && name == null && prename == null) {
			PersistenceManager pm = PMF.get().getPersistenceManager();

			Query query = pm.newQuery(Location.class);
			query.setFilter("name == locationName");
			query.declareParameters("String locationName");

			if (location.equals("")) {
				resp.getWriter().println("Please specify a location");
				resp.setStatus(400);
			} else {
				try {
					List<Location> results = (List<Location>) query
							.execute(location);

					if (!results.isEmpty()) {
						Location result = results.get(0);
						Gson gson = new Gson();
						String json = gson.toJson(result.getEvents());
						resp.setStatus(200);
						resp.getWriter().println(
								URLEncoder.encode(json, "UTF-8"));
					} else {
						resp.setStatus(200);
						resp.getWriter().println(
								"no events for location: " + location + " yet");
					}
				} finally {
					query.closeAll();
					pm.close();
				}
			}
		}

		// Query for a Person
		else if (name != null && prename != null && location == null
				&& title == null) {
			PersistenceManager pm = PMF.get().getPersistenceManager();
			Query query = pm.newQuery(Person.class);
			query.setFilter("prename == prenameString && name == nameString");
			query.declareParameters("String prenameString, String nameString");

			try {
				List<Person> results = (List<Person>) query.execute(prename,
						name);

				if (!results.isEmpty()) {
					Person person = results.get(0);
					List<EventStatus> eventList = person.getEvents();

					if (!eventList.isEmpty()) {
						for (EventStatus status : eventList) {
							Query eventQuery = pm.newQuery(Event.class);
							eventQuery.setFilter("title == titleParam");
							eventQuery.declareParameters("String titleParam");
							List<Event> events = (List<Event>) eventQuery
									.execute(status.getEvent());

							if (!events.isEmpty()) {
								for (Event e : events) {
									toJson.add(e);
								}
							}
						}

						if (!toJson.isEmpty()) {
							Gson gson = new Gson();
							String json = gson.toJson(toJson);
							resp.setStatus(200);
							resp.getWriter().println(
									URLEncoder.encode(json, "UTF-8"));
						} else {
							resp.setStatus(200);
							resp.getWriter().println("no events yet");
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				resp.setStatus(400);
			} finally {
				pm.close();
			}
		}

		// Query for only one Event
		else if (title != null && name == null && prename == null
				&& location == null) {
			PersistenceManager pm = PMF.get().getPersistenceManager();

			Query eventQuery = pm.newQuery(Event.class);
			eventQuery.setFilter("title == titleParam");
			eventQuery.declareParameters("String titleParam");
			List<Event> events = (List<Event>) eventQuery.execute(title);

			if (!events.isEmpty()) {
				for (Event e : events) {
					toJson.add(e);
				}
			}

			if (!toJson.isEmpty()) {
				Gson gson = new Gson();
				String json = gson.toJson(toJson);
				resp.setStatus(200);
				resp.getWriter().println(URLEncoder.encode(json, "UTF-8"));
			} else {
				resp.setStatus(200);
				resp.getWriter().println("no events yet");
			}

			pm.close();
		}

		// General query - return all the Events
		else {
			PersistenceManager pm = PMF.get().getPersistenceManager();

			Query eventQuery = pm.newQuery(Event.class);
			List<Event> events = (List<Event>) eventQuery.execute();

			if (!events.isEmpty()) {
				for (Event e : events) {
					toJson.add(e);
				}
			}

			if (!toJson.isEmpty()) {
				Gson gson = new Gson();
				String json = gson.toJson(toJson);
				resp.setStatus(200);
				resp.getWriter().println(URLEncoder.encode(json, "UTF-8"));
			} else {
				resp.setStatus(200);
				resp.getWriter().println("no events yet");
			}

			pm.close();
		}
	}
}
